package la.iok.hzsvn.lewin.movie.service;

import la.iok.hzsvn.lewin.movie.core.RoleEnum;
import la.iok.hzsvn.lewin.movie.core.Token;
import la.iok.hzsvn.lewin.movie.core.exception.ErrorCode;
import la.iok.hzsvn.lewin.movie.entity.KeyValue;
import la.iok.hzsvn.lewin.movie.mapper.KeyValueMapper;
import la.iok.hzsvn.lewin.mybatis.service.BaseServiceImpl;
import la.iok.hzsvn.share.annotations.NotNull;
import la.iok.hzsvn.share.annotations.Nullable;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class KeyValueServiceImpl extends BaseServiceImpl<KeyValue, KeyValueMapper,Long> implements KeyValueService {
    private static final String[] TIME_TYPES = new String[]{KeyValueService.month,KeyValueService.season,KeyValueService.year};
    @Value("${spring.application.name}")
    private String serverName;
    public KeyValueServiceImpl(KeyValueMapper mapper) {
        super(mapper);
    }

    @Override
    public Float VIPRoomPrice(String type) {
        ErrorCode.VIP_ROOM_TIME_TYPE_ERROR.assertAnyOf(type, TIME_TYPES,type,String.join(",",TIME_TYPES));
        KeyValue keyValue = select("key","room." + type);
        ErrorCode.VIP_ROOM_TIME_TYPE_NOT_CONFIG.assertNotNull(keyValue,type);
        String v = keyValue.getValue();
        ErrorCode.VIP_ROOM_TIME_TYPE_NOT_CONFIG.assertNotNull(v,type);
        try {
            return Float.parseFloat(v);
        }catch (NumberFormatException e){
            ErrorCode.PROPERTY_CHECK_ERROR.fail(type,"值只能是数字");
            return null;
        }
    }

    @Override
    public void updateVIPRoomPrice(@Nullable String type, @Nullable Float price) {
        ErrorCode.PROPERTY_CHECK_ERROR.assertNotNull(price,"价格","数值不能为空");
        ErrorCode.PROPERTY_CHECK_ERROR.assertTrue(price > 0,"价格","数值必须大于0");
        ErrorCode.VIP_ROOM_TIME_TYPE_ERROR.assertAnyOf(type, TIME_TYPES,type,String.join(",",TIME_TYPES));
        int c = mapper.update("room." + type,String.valueOf(price));
        if(c == 0){
            KeyValue entity = new KeyValue();
            entity.setKey("room." + type);
            entity.setValue(String.valueOf(price));
            entity.setServerName(serverName);
            insertSelective(entity);
        }
    }

    @Override
    public boolean obsReadEnabled() {
        KeyValue keyValue = select("key",obsEnableClientReadKey);
        return keyValue != null && "1".equals(keyValue.getValue());
    }

    @Override
    public void enableObsRead(@NotNull Token token) {
        enableKey(token,obsEnableClientReadKey);
    }

    @Override
    public void cancelObsRead(@NotNull Token token) {
        cancelKey(token,obsEnableClientReadKey);
    }

    @Override
    public boolean obsWriteEnabled() {
        KeyValue keyValue = select("key",obsEnableClientWriteKey);
        return keyValue != null && "1".equals(keyValue.getValue());
    }

    @Override
    public void enableObsWrite(@NotNull Token token) {
        enableKey(token,obsEnableClientWriteKey);
    }

    @Override
    public void cancelObsWrite(@NotNull Token token) {
        cancelKey(token,obsEnableClientWriteKey);
    }

    private void enableKey(@NotNull Token token, @NotNull String enableKey) {
        ErrorCode.ADMIN_DENIED.assertTrue(token.hasAuthority(RoleEnum.Admin));
        KeyValue keyValue = select("key", enableKey);
        if(keyValue != null){
            update(keyValue.getId(),"value","1");
        }else{
            keyValue = new KeyValue();
            keyValue.setKey(enableKey);
            keyValue.setValue("1");
            keyValue.setServerName(serverName);
            insertSelective(keyValue);
        }
    }

    private void cancelKey(@NotNull Token token, @NotNull String key){
        ErrorCode.ADMIN_DENIED.assertTrue(token.hasAuthority(RoleEnum.Admin));
        KeyValue keyValue = select("key",key);
        if(keyValue != null){
            update(keyValue.getId(),"value","0");
        }
    }
}
